package com.glsc.ngateway.platform.service.cmdb;

import cn.hutool.core.collection.CollectionUtil;
import com.glsc.ngateway.common.api.common.enums.DictConstant;
import com.glsc.ngateway.common.base.domain.mysql.cmdb.CmdbDict;
import com.glsc.ngateway.common.base.domain.mysql.cmdb.CmdbDictValue;
import com.glsc.ngateway.common.base.repo.mysql.cmdb.CmdbDictRepository;
import com.glsc.ngateway.common.api.common.utils.PageUtil;
import com.glsc.ngateway.platform.service.DictService;
import com.glsc.ngateway.platform.service.SystemConfigService;
import com.glsc.ngateway.platform.utils.SpecificationUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class CmdbDictService {
    private static Logger logger = LoggerFactory.getLogger(DictService.class);

    @Resource
    private CmdbDictRepository dictRepository;

    @Resource
    private SystemConfigService systemConfigService;

    /**
     * 创建实体
     *
     * @param dict
     */
    public CmdbDict saveDict(CmdbDict dict) {
        if (dict.getDictDeleted() == null) {
            dict.setDictDeleted(DictConstant.NO_DELETED);
        }
        return dictRepository.save(dict);
    }

    /**
     * 查找实体
     *
     * @param id
     * @return
     */
    public CmdbDict findById(Integer id) {
        Optional<CmdbDict> optional = dictRepository.findById(id);
        if (optional.isPresent()) {
            return optional.get();
        } else {
            return null;
        }
    }

    public void deleteById(Integer id) {
        dictRepository.deleteById(id);
    }

    /**
     * 分页条件查询
     *
     * @param pageNo
     * @param pageSize
     * @param param
     * @return
     */
    public Page<CmdbDict> findPage(int pageNo, int pageSize, Map<String, Object> param) {
        Sort.Direction direction = Sort.Direction.DESC;
        String sort = "dictId";

        pageNo = PageUtil.initPageNo(pageNo);
        pageSize = PageUtil.initPageSize(pageSize);

        Pageable pageable = PageRequest.of(pageNo - 1, pageSize, direction, sort);
        return dictRepository.findAll(SpecificationUtil.buildSpecification(param, CmdbDict.class), pageable);
    }

    /**
     * 根据条件查询List
     */
    public List<CmdbDict> findList(Map<String, Object> param) {
        return dictRepository.findAll(SpecificationUtil.buildSpecification(param, CmdbDict.class));
    }

    public Page<CmdbDict> findPage(int page, int size, String tag) {
        Sort.Direction direction = Sort.Direction.DESC;
        String sort = "dictId";
        Pageable pageable = PageRequest.of(page - 1, size, direction, sort);
        return dictRepository.findAll(new Specification<CmdbDict>() {
            @Override
            public Predicate toPredicate(Root<CmdbDict> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                Predicate p = criteriaBuilder.and(criteriaBuilder.greaterThan(root.get("dictId").as(Integer.class), 0));
                if (null != tag && tag.length() > 0) {
                    Predicate p1 = criteriaBuilder.like(root.get("dictName").as(String.class), "%" + tag + "%");
                    Predicate orp = criteriaBuilder.or(p1);
                    p = criteriaBuilder.and(p, orp);
                }
                return p;
            }
        }, pageable);
    }

    public CmdbDict findByName(String dictName) {
        return dictRepository.findByDictNameAndDictDeleted(dictName, 0);
    }

    public CmdbDict findByDictCode(String dictCode) {
        return dictRepository.findByDictCodeAndDictDeleted(dictCode, 0);
    }


    /**
     * 查询产品列表虚拟字典
     */
//    public CmdbDict findDictOfProdListVDict() {
//        List<ProductBasicInfoDto> allProdList = CacheManager.getProductBasicInfoAll();
//        CmdbDict allProdDict = new CmdbDict();
//        allProdDict.setDictCode(DictConstant.DICT_VM_PROD_LIST);
//        List<DictValue> dictValueList = new ArrayList<>();
//        allProdDict.setDictValues(dictValueList);
//        for (ProductBasicInfoDto productBasicInfoDto : allProdList) {
//            DictValue item = new DictValue();
//            item.setDictCode(DictConstant.DICT_VM_CUSTODIAN);
//            item.setValue(productBasicInfoDto.getProdUniqueId());
//            item.setLabel(productBasicInfoDto.getProdName());
//            dictValueList.add(item);
//        }
//        return allProdDict;
//    }

    public List<CmdbDict> findByParentCode(String dictCode) {
        Map<String, Object> param = new HashMap<>();
        param.put("EQ_parentCode", Integer.parseInt(dictCode));
        param.put("EQ_dictDeleted", 0);
        return dictRepository.findAll(SpecificationUtil.buildSpecification(param, CmdbDict.class));
    }

    public List<CmdbDict> findAllByDictCodeList(List<String> dictCodeList) {
        return dictRepository.findAllByDictCodeInAndDictDeleted(dictCodeList, DictConstant.NO_INT_0);
    }

    /**
     * @param productDictCodeList 要查询的字典编码列表，如果为NULL则查询全部
     * @param revert 如revert为true则表示字典：标签，否则返回标签：字典反向的map【暂时不用】
     * @return 查询产品中用到的所有字典信息
     */
//    public Map<String, Map<String, String>> findByDictCodeList(List<String> productDictCodeList, String revert) {
//        //默认返回常规的字典：标签的值，一般在导入需要根据中文名反向转换字典时使用revert=Y
//        if (StrUtil.isEmpty(revert)) {
//            revert = DictConstant.NO;
//        }
//
//        if(CollectionUtils.isEmpty(productDictCodeList)||productDictCodeList.contains(DictConstant.ALL_DICT_CODE_LIST)){
//            Map<String, Map<String, String>> allDictMap= CacheManager.getAllDictMapFromRedis();
//            logger.info("查询所有字典项目="+allDictMap.size());
//
//            return allDictMap;
//        }
//
//        //根据字典codelist查询字典list
//        List<CmdbDict> dictList = CacheManager.getDictListFromRedis(productDictCodeList);
//
//        final Map<String, Map<String, String>> resultMap = new HashMap<>();
//
//        //遍历字典list，生成返回结果
//        String finalRevert = revert;
//        dictList.stream().peek(dict -> {
//            String dictCode = dict.getDictCode();
//            Map<String, String> valueLabelMap;
//            if(DictConstant.YES.equals(finalRevert)){
//                valueLabelMap = dict.getDictValues().stream().collect(Collectors.toMap(DictValue::getLabel, DictValue::getValue,(k1, k2)->k1));
//            }else {
//                valueLabelMap = dict.getDictValues().stream().collect(Collectors.toMap(DictValue::getValue, DictValue::getLabel));
//            }
//            resultMap.put(dictCode, valueLabelMap);
//        }).collect(Collectors.toList());
//
//        logger.info("查询字典项目="+resultMap.size());
//
//        return resultMap;
//    }


    /**
     * 根据系统配置查询字典项信息
     */
    public CmdbDict findByConfigCode(String dictCode, String configCode) {
        CmdbDict dict = this.findByDictCode(dictCode);
        List<CmdbDictValue> dictValues = dict.getDictValues();

        if (CollectionUtil.isEmpty(dictValues)) {
            return dict;
        }
        //过滤出系统项配置里的字典值项
        List<String> dictValueList = systemConfigService.findConfigValueAsListByCode(configCode);
        dictValues = dictValues.stream().filter(dictValue -> dictValueList.contains(dictValue.getValue())).collect(Collectors.toList());
        dict.setDictValues(dictValues);
        return dict;
    }
}
